//
//  AudioRecorderViewController.m
//  ALittleReminder
//
//  Created by George on 15/11/2011.
//

#import "AudioRecorderViewController.h"

enum ViewState
{
    noRecord, noPlay, stop, record, pauseRecord, play, pausePlay, 
};
enum ViewState viewStateTransition[7][2] = 
{
    {noPlay,record},
    {noPlay,record},
    {play,record},
    {pauseRecord,stop},
    {record,stop},
    {pausePlay,stop},
    {play,stop},
};
float backGroundPower = 0;

@implementation AudioRecorderViewController{
    enum ViewState currentState;
    
    AVAudioPlayer *audioPlayer;
    AVAudioRecorder *audioRecorder;
    
    NSArray *viewStateDisplay;
    
    NSURL *audioUrl;
    
    AlertManagedObject * myAlert;
    
    bool updating;
}
@synthesize removeSoundButten;
@synthesize progessSlider;
@synthesize playOrPauseButten;
@synthesize recordOrStopButten;



- (id)initWithAlert:(AlertManagedObject *)alert
{
    self = [self initWithNibName:@"AudioRecorderViewController" bundle:nil];
    if (self) {
        myAlert = alert;
    }
    return self;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        viewStateDisplay = [NSArray arrayWithObjects: @"Remove Sound"/*not used*/, @"play"/*hidden*/, @"stop", @"record", @"pause", @"play", @"pause", nil];
        currentState = -1;//start from undefined state
    }
    return self;
}

- (void)updateProgress
{
    //NSLog(@"updateProgress");
    switch (currentState) {
        case noRecord:
            //break;
        case noPlay:
            //break;
        case stop:
            progessSlider.value = 0;
            break;
        case record:
            [audioRecorder updateMeters];
            progessSlider.maximumValue = 100;
            float peak = [audioRecorder averagePowerForChannel:0];
            if (peak < backGroundPower) {
                backGroundPower = peak;
            }
            progessSlider.value = peak-backGroundPower;
            break;
        case pauseRecord:
            
            break;
        case play:
            //break;
        case pausePlay:
            progessSlider.maximumValue = audioPlayer.duration;
            progessSlider.value = audioPlayer.currentTime;
            break;
        default:
            break;
    }
    
    if(updating){
        SEL update = @selector(updateProgress);
        [self performSelector:update withObject:nil afterDelay:0.1];
    }
    
}

- (IBAction)onRemoveSound:(id)sender {
    [self changeStateTo:noRecord];
}

- (IBAction)onPlayOrPause:(id)sender 
{
    [self changeStateTo:viewStateTransition[currentState][0]];
}

- (IBAction)onRecordOrStop:(id)sender 
{
    [self changeStateTo:viewStateTransition[currentState][1]];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    [self changeStateTo:stop];
}
- (void)changeStateTo:(enum ViewState) nextState
{
    if (currentState == nextState) {
        return;
    }
    
    switch (nextState) {
        case noRecord:
            [self stopAll];
            [audioRecorder deleteRecording];
            removeSoundButten.hidden = YES;
            playOrPauseButten.hidden = YES;
            break;
        case noPlay:
            nextState = currentState;
            break;
        case stop:
            [self stopAll];
            break;
        case record:
            if([audioRecorder record]){
                NSLog(@"start recording");
                removeSoundButten.hidden = NO;
                playOrPauseButten.hidden = NO;
                audioPlayer = nil;//reset the audio player since the audio file is updating
            }else{
                NSLog(@"start recording error");
                nextState = currentState;
            }
            break;
        case pauseRecord:
            [audioRecorder pause];
            break;
        case play:
            if(!audioPlayer){
                [self creatAudioPlayer];
            }
            if([audioPlayer play]){
                NSLog(@"start playing");
            }else{
                NSLog(@"start playing error");
                nextState = currentState;
            }
            break;
        case pausePlay:
            [audioPlayer pause];
            break;
        default:
            break;
    }
    currentState = nextState;
    NSString *title = [viewStateDisplay objectAtIndex:viewStateTransition[currentState][0]];
    [playOrPauseButten setTitle:title forState:UIControlStateNormal];
    title = [viewStateDisplay objectAtIndex:viewStateTransition[currentState][1]];
    [recordOrStopButten setTitle:title forState:UIControlStateNormal];
}
- (void)stopAll{
    if (audioRecorder.isRecording) {
        //NSLog(@"recorded for %@", [audioRecorder currentTime]);
        [audioRecorder stop];
    }
    if (audioPlayer.isPlaying) {
        [audioPlayer stop];
        audioPlayer.currentTime = 0;
    }
}
- (IBAction)onDone:(id)sender {
    if (currentState != noRecord) {
        [self changeStateTo:stop];
    }
    //save to myAlert in viewDidUnload
    [self dismissModalViewControllerAnimated:YES];
}


- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

- (void) creatAudioPlayer
{
    // Init audio with playback capability
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioUrl error:nil];
    if (audioPlayer) {
        audioPlayer.numberOfLoops = 0;
        audioPlayer.delegate = self;
        [audioPlayer prepareToPlay];
    }
}

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    // Init audioRecorder
    if ( myAlert.audioFileName) {
        audioUrl = [[NSURL alloc] initWithString:myAlert.audioFileName];
        [self changeStateTo:stop];
    }else{
        //generate a uniq file name
        audioUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/_%@_record.caf", [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject], [NSDate date]]];
        [self changeStateTo:noRecord];
    }
    //NSLog(@"%@",audioUrl);
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryRecord error:nil];
    
    NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] initWithCapacity:10];
    
    [recordSettings setObject:[NSNumber numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:16000.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];   
    
    NSError *error = nil;
    audioRecorder = [[ AVAudioRecorder alloc] initWithURL:audioUrl settings:recordSettings error:&error];
    if (!audioRecorder) {
        NSLog(@"Error: %@" , [error localizedDescription]); 
    }else{
        audioRecorder.meteringEnabled = YES;
    }

}


- (void)viewWillUnload
{

}
- (void)viewDidUnload
{

    myAlert=nil;
    audioPlayer=nil;
    audioRecorder=nil;
    viewStateDisplay=nil;
    audioUrl=nil;
    [self setPlayOrPauseButten:nil];
    [self setRecordOrStopButten:nil];
    [self setRemoveSoundButten:nil];
    [self setProgessSlider:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    updating = true;
    [self updateProgress];
}
- (void)viewWillDisappear:(BOOL)animated
{
    updating = false;
    if (currentState == noRecord) {
        myAlert.audioFileName = nil;
    }else{
        [self stopAll];
        myAlert.audioFileName = [audioUrl absoluteString];
    }
    [super viewWillDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


@end
